#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <cstdlib>

//C语言阶段
//int Add1(int x, int y)
//{
//	return x + y;
//}
//
//double Add2(double x, double y)
//{
//	return x + y;
//}
//
////C++函数重载
//int Add(int x, int y)
//{
//	return x + y;
//}
//
//double Add(double x, double y)
//{
//	return x + y;
//}

//template <typename T>
//T Add(T x, T y)
//{
//	return x + y;
//}

//int Add(int x, int y)
//{
//	return x + y;
//}


//template <typename T1, class T2>
//void func(T1 x, T2 y)
//{
//	//……
//}

//int main()
//{
//	int a = 1;
//	double b = 19.2;
//
//	std::cout << Add<int>(a, b) << std::endl;
//
//	return 0;
//}


//int main()
//{
//	std::cout << Add(1, 2) << std::endl;
//
//	std::cout << Add(1, 2.0) << std::endl;
//
//	std::cout << Add(1, (int)2.0) << std::endl;
//
//	std::cout << Add((double)1, 2.0) << std::endl;
//
//	std::cout << Add<int>(1, 2.0) << std::endl;
//
//	return 0;
//}

//
//template <typename T>
//T Add(T x, T y)
//{
//	return x + y;
//}
//
//int main()
//{
//	Add(1,2);
//
//	Add(1.0, 2.0);
//
//	return 0;
//}


//template <typename T>
//T Add(T x, T y)
//{
//	return x + y;
//}
//
//int Add(int x, int y)
//{
//	return x + y;
//}
//
//int main()
//{
//	Add(1, 2);//调用非模板函数
//
//	Add(1.0, 2.5);//调用模板函数
//
//	return 0;
//}

//template <typename T1, typename T2>
//T1 Add(T1 x, T2 y)
//{
//	return x + y;
//}
//
//int Add(int x, int y)
//{
//	return x + y;
//}
//
//int main()
//{
//	Add(1, 2);//调用非模板函数
//
//	//调用模板函数
//	//此时如果调用非模板函数会发生隐式类型转换，会丢失精度
//	//而对于模板来说，可以生成一个针对于该实参的专属的函数，不会丢失精度
//	//所以对编译器而言此时调用模板函数是一个更好的选择
//	Add(1, 2.5);
//
//	return 0;
//}


//template <typename T1, typename T2>
//class A
//{
//public:
//	A()
//	{
//		std::cout << "A()" << std::endl;
//	}
//private:
//	T1 x;
//	T2 y;
//};
//
//int main()
//{
//	A<int, int> a1;
//	A<int, double> a2;
//
//	return 0;
//}


void func1()
{
	int* p1 = (int*)malloc(sizeof(int));
	//检查
	if (p1 == NULL)
	{
		perror("malloc fail");
		return;
	}

	int* p2 = (int*)calloc(1, sizeof(int));
	//检查

	int* p3 = (int*)realloc(p1, 8);
	//检查


	free(p1);
	free(p2);
	free(p3);
	p1 = NULL;
	p2 = NULL;
	p3 = NULL;
}

void func2()
{
	//申请一个int类型的空间
	int* p1 = new int;

	//申请一个double类型的空间并初始化为1.0
	double* p2 = new double(1.0);

	//申请数组,大小为10个char
	char* p3 = new char[10] {0};

	delete p1;
	delete p2;
	delete[] p3;

}

class A
{
public:
	A()
	{
		std::cout << "A()" << std::endl;
	}

	A(int a)
		:_a(a)
	{
		std::cout << "A()" << std::endl;
	}
	~A()
	{
		std::cout << "~A()" << std::endl;
	}

private:
	int _a;
};

void func3()
{
	//A* p1 = (A*)malloc(sizeof(A));
	////检查
	//free(p1);

	A a1(1);
	A a2(2);
	A a3(3);

	A* p1 = new A[10]{ a1,a2,a3 };

	A* p2 = new A[10]{A(1),A(2)};

	A* p3 = new A[10]{ 1,2,3 };
	delete[] p2;
}

void func4()
{
	//int* p1 = new int(1);
	//free(p1);

	//int* p2 = (int*)malloc(sizeof(int));
	////检查
	//delete p2;

	A* p1 = new A[10];
	std::cout << sizeof(*p1) << std::endl;

	A* p2 = (A*)malloc(sizeof(A) * 10);
	//检查


	std::cout << sizeof(*p2) << std::endl;


	free(p1);
	delete[] p2;
}


void func5()
{
	int* p1 = new int(1);

	delete p1;
}

class B
{
public:
	B()
	{
		std::cout << "B()" << std::endl;
	}

	B(const int a)
		:_a(a)
	{
		std::cout << "B()" << std::endl;
	}

	~B()
	{
		std::cout << "~B()" << std::endl;
	}

private:
	int _a;
};


void func6()
{

	B* p1 = new B[10];
	//free(p1);出错
	//delete p1;出错
	delete[]p1;



	/*int* p1 = new int[10];
	free(p1);*/
	//delete p1;
	//delete[]p1;

	/*B* p1 = new B[10];

	delete p1;*/
}

//int main()
//{
//	func6();
//
//	return 0;
//}
//
//void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc))
//{
//	// try to allocate size bytes
//	void* p;
//	while ((p = malloc(size)) == 0)
//		if (_callnewh(size) == 0)
//		{
//			// report no memory
//			// 如果申请内存失败了，这里会抛出bad_alloc 类型异常
//			static const std::bad_alloc nomem;
//			_RAISE(nomem);
//		}
//	return (p);
//}
//
///*
//operator delete: 该函数最终是通过free来释放空间的
//*/
//void operator delete(void* pUserData)
//{
//	_CrtMemBlockHeader* pHead;
//	RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
//	if (pUserData == NULL)
//		return;
//	_mlock(_HEAP_LOCK); /* block other threads */
//	__TRY
//		/* get a pointer to memory block header */
//		pHead = pHdr(pUserData);
//	/* verify block type */
//	_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
//	_free_dbg(pUserData, pHead->nBlockUse);
//	__FINALLY
//		_munlock(_HEAP_LOCK); /* release other threads */
//	__END_TRY_FINALLY
//		return;
//}
///*
//free的实现
//*/
//#define free(p) _free_dbg(p, _NORMAL_BLOCK)


int main()
{
	int i = 0;
	for (i = 28; i <= 54; i++)
	{
		std::cout << "hello " << i << std::endl;
	}

	return 0;
}